subroutine readextn(lunit,t_array0,myrank)
  use param
  use global_param,only:n_ext
  use global_param,only:extern_type
  use label_data_param,only:obj_type
  implicit none

  interface
     integer function str2label(str)
       character :: str*(*)
     end function str2label
     
     function reallocExternEventObjectSet(p,n)
       use derived
       type(ObjectSet),pointer,dimension(:) :: &
            reallocExternEventObjectSet,p
       integer,intent(in) :: n
     end function reallocExternEventObjectSet

     function reallocInt(p,n)
       integer,pointer,dimension(:) :: reallocInt,p
       integer,intent(in) :: n
     end function reallocInt
  end interface

  integer,intent(in) :: lunit,t_array0(8),myrank

  integer :: len_str,asci_code
  character(len=len_linebuf) :: eatline,str
  character(len=len_wordbuf),dimension(max_n_word) :: eatword
  character(len=8) :: d_time_str

  integer :: i,j,k,n,m,l
  integer :: nunit,itype,nobj,lid,index,ierr
  real(dbl) :: e1,e2,p
  real(dbl) :: pkae,dx,dy,dz
  integer :: in1,in2,pos1,pos2

  logical :: foo

  if (n_ext.eq.0) return

  in1=1
  in2=2

  call log_msg1(lunit,"")
  call log_msg1(lunit,"Message from the subourinte (readextn)")
  call log_msg1(lunit,"")

  write(lunit,'(1x,"Number of external events=",1x,i0)') &
       n_ext
  nunit=1

  ! read the cascade files and cdf for neutron irradiation
  do i=1,n_ext

     itype=extern_type(i)%event_type

     if (itype.eq.2) cycle
     if (itype.eq.3) cycle

     call log_msg1(lunit,"")

     pos1=0

     pos2=pos1+3
     write(str(pos1+1:pos2),'("[",i1,"]")') i
     pos1=pos2

     pos2=pos1+24
     write(str(pos1+1:pos2),'(1x,"neutron irradiation (1)")')
     pos1=pos2

     call log_msg1_indent(lunit,in1,str(1:pos2))
     
     ! read cdf for subcascade density
     open(unit=nunit,file=extern_type(i)%cas_filename,status='old')
     ! number of bins
     read(nunit,*) n
     ! allocate energy bins
     extern_type(i)%n_cas=n
     allocate(extern_type(i)%cgrid(n))
     allocate(extern_type(i)%cprob(n))
     allocate(extern_type(i)%cascade_list(n))
     allocate(extern_type(i)%count_cascade(n))
     ! write the table to the log file
     call drawline(lunit,in1,42)
     write(str(1:38),'(2x,"ID",2x,&
                       3x,"e1(eV)",3x,&
                       3x,"e2(eV)",3x,&
                       3x,"int_R")')
     call log_msg1_indent(lunit,in1,str(1:38))
     call drawline(lunit,in1,42)

     ! initialize the length of the cdf for subcascade density
     call log_msg1_indent(lunit,in1,"> Subcascade density")
     extern_type(i)%clength=0

     ! read the cdf
     do j=1,n
        ! Read from the file
        read(nunit,*) e1,e2,p
        extern_type(i)%cgrid(j)=e2
        extern_type(i)%cprob(j)=p
        extern_type(i)%cascade_list(j)%nlist=0
        nullify(extern_type(i)%cascade_list(j)%clist)
        extern_type(i)%count_cascade(j)=0
        ! Print to the log file
        write(str(1:41),'("[",i3.3,"]",1x,&
             1pe11.5,1x,1pe11.5,1x,1pe11.5)') &
             j,e1,e2,p
        call log_msg1_indent(lunit,in1,str(1:41))
     end do

     ! set the length of the cdf for subcascade density
     extern_type(i)%clength=p

     close(nunit)

     ! read cdf for dpa calculation
     open(unit=nunit,file=extern_type(i)%dpa_filename,status='old')
     ! number of bins
     read(nunit,*) n
     extern_type(i)%n_dpa=n
     allocate(extern_type(i)%dgrid(n))
     allocate(extern_type(i)%dprob(n))
     allocate(extern_type(i)%count_dpa(n))

     ! initialize the length of the cdf for dpa calculation
     call log_msg1(lunit,"")
     call log_msg1_indent(lunit,in1,"> Recoil spectrum")
     extern_type(i)%dlength=0

     ! read the cdf
     do j=1,n
        read(nunit,*) e1,e2,p
        extern_type(i)%dgrid(j)=e2
        extern_type(i)%dprob(j)=p
        extern_type(i)%count_dpa(j)=0
        ! Print to the log file
        write(str(1:41),'("[",i3.3,"]",1x,&
             1pe11.5,1x,1pe11.5,1x,1pe11.5)') &
             j,e1,e2,p
        call log_msg1_indent(lunit,in1,str(1:41))
     end do

     ! set the length of the cdf for dpa calculation
     extern_type(i)%dlength=p

     close(nunit)

     call drawline(lunit,in1,42)

     call log_msg1(lunit,"")
     write(lunit,'(1x,"File for cascade sample : ",a)') &
          trim(extern_type(i)%filename)

     ! read cascade samples
     open(unit=nunit,file=extern_type(i)%filename,status='old')

     n=0
     do
        read(nunit,'(a)',end=100,err=101) eatline
        len_str=len_trim(eatline)
        if (len_str.eq.0) cycle
        eatline=adjustl(eatline)
        asci_code=ichar(eatline(1:1))
        if (asci_code.eq.ccode) cycle
        read(eatline(1:len_str),*,end=102) &
             (eatword(j),j=1,max_n_word)
102     continue

        ! read energy of pka
        read(eatword(2),*) pkae
        read(eatword(4),*) nobj

        foo=.true.
        ! extern_type(i)%objset(n)%n_obj
        ! find the corresponding energy group among the bins
        do j=1,extern_type(i)%n_cas
           if (pkae.le.extern_type(i)%cgrid(j)) then
              ! save the group index
              m=j
              foo=.false.
              exit
           end if
        end do

        ! if the group is not found, then,
        ! ignore it.
        if (foo) then
           l=0
           do
              read(nunit,'(a)') eatline
              len_str=len_trim(eatline)
              if (len_str.eq.0) cycle
              eatline=adjustl(eatline)
              asci_code=ichar(eatline(1:1))
              if (asci_code.eq.ccode) cycle
              l=l+1
              if (l.eq.nobj) exit
           end do
        end if
        if (foo) cycle

        n=n+1
        extern_type(i)%n_objset=n

        extern_type(i)%objset=>&
             reallocExternEventObjectSet(&
             extern_type(i)%objset,n)

        extern_type(i)%objset(n)%pka_e=pkae
        extern_type(i)%objset(n)%n_obj=nobj

        ! Write to the log file
        call log_msg1(lunit,"")
        write(lunit,'(1x,"[",i3.3,"]",&
                      1x,"PKA_E=",1pe11.5,1x,"(eV)",&
                      4x,"No. of objects=",i0,&
                      4x,"SID=",i0)') &
                      n,pkae,nobj,m

        allocate(extern_type(i)%objset(n)%obj(nobj))

        l=0
        do
           ! make it clean 
           ! to treat if the words for direction are blank
           eatline=""
           do j=1,max_n_word
              eatword(j)=""
           end do
           ! read a line
           read(nunit,'(a)') eatline
           len_str=len_trim(eatline)
           if (len_str.eq.0) cycle
           eatline=adjustl(eatline)
           asci_code=ichar(eatline(1:1))
           if (asci_code.eq.ccode) cycle
           read(eatline(1:len_str),*,end=103) &
                (eatword(j),j=1,max_n_word)
103        continue
           ! c1:index
           ! c2:label
           ! c3:px
           ! c4:py
           ! c5:pz
           ! c6:dx or blank
           ! c7:dy or blank
           ! c8:dz or blank

           ! read index
           read(eatword(1),*) index

           ! read the label of the object
           lid=str2label(eatword(2))
           if (lid.eq.0) then
              call terminal_msg1(eatline)
              call abnormal_stop("readextn",&
                   "Unrecognized label is found in the cascade file.")
           end if
           
           l=l+1
           extern_type(i)%objset(n)%obj(l)%obj_type=lid

           ! read the position
           read(eatword(3),*) extern_type(i)%objset(n)%obj(l)%pos(1)
           read(eatword(4),*) extern_type(i)%objset(n)%obj(l)%pos(2)
           read(eatword(5),*) extern_type(i)%objset(n)%obj(l)%pos(3)

           ! read the direction of alignment
           read(eatword(6),*,err=104,iostat=ierr) dx
           read(eatword(7),*,err=104,iostat=ierr) dy
           read(eatword(8),*,err=104,iostat=ierr) dz
104        continue

           ! if the direction is not specified,
           ! set dir as 1.
           if (ierr.ne.0) then
              extern_type(i)%objset(n)%obj(l)%dir=1
              dx=0
              dy=0
              dz=0
           else
              extern_type(i)%objset(n)%obj(l)%dir=0
           end if

           extern_type(i)%objset(n)%obj(l)%vec(1)=dx
           extern_type(i)%objset(n)%obj(l)%vec(2)=dy
           extern_type(i)%objset(n)%obj(l)%vec(3)=dz

           ! Write to the log file
           pos1=0

           pos2=pos1+11
           write(str(pos1+1:pos2),'(1x,a10)') &
                trim(obj_type(lid)%name)
           pos1=pos2

           if (extern_type(i)%objset(n)%obj(l)%dir.eq.0) then
              pos2=pos1+12
              write(str(pos1+1:pos2),'(1x,1pe11.5)') &
                   extern_type(i)%objset(n)%obj(l)%pos(1)
              pos1=pos2

              pos2=pos1+12
              write(str(pos1+1:pos2),'(1x,1pe11.5)') &
                   extern_type(i)%objset(n)%obj(l)%pos(2)
              pos1=pos2

              pos2=pos1+12
              write(str(pos1+1:pos2),'(1x,1pe11.5)') &
                   extern_type(i)%objset(n)%obj(l)%pos(3)
              pos1=pos2

              pos2=pos1+8
              write(str(pos1+1:pos2),'(1x,"(dir=0)")')
              pos1=pos2

              pos2=pos1+3
              write(str(pos1+1:pos2),'(1x,i2)') &
                   int(extern_type(i)%objset(n)%obj(l)%vec(1))
              pos1=pos2

              pos2=pos1+3
              write(str(pos1+1:pos2),'(1x,i2)') &
                   int(extern_type(i)%objset(n)%obj(l)%vec(2))
              pos1=pos2

              pos2=pos1+3
              write(str(pos1+1:pos2),'(1x,i2)') &
                   int(extern_type(i)%objset(n)%obj(l)%vec(3))
              pos1=pos2
           else
              pos2=pos1+12
              write(str(pos1+1:pos2),'(1x,1pe11.5)') &
                   extern_type(i)%objset(n)%obj(l)%pos(1)
              pos1=pos2

              pos2=pos1+12
              write(str(pos1+1:pos2),'(1x,1pe11.5)') &
                   extern_type(i)%objset(n)%obj(l)%pos(2)
              pos1=pos2

              pos2=pos1+12
              write(str(pos1+1:pos2),'(1x,1pe11.5)') &
                   extern_type(i)%objset(n)%obj(l)%pos(3)
              pos1=pos2

              pos2=pos1+8
              write(str(pos1+1:pos2),'(1x,"(dir=1)")')
              pos1=pos2
           end if
           call log_msg1_indent(lunit,8,str(1:pos2))

           if (l.eq.nobj) exit

        end do

        ! Save the cascade index to the energy group
        extern_type(i)%cascade_list(m)%nlist=&
             extern_type(i)%cascade_list(m)%nlist+1
        l=extern_type(i)%cascade_list(m)%nlist
        extern_type(i)%cascade_list(m)%clist=>&
             reallocInt(&
             extern_type(i)%cascade_list(m)%clist,l)
        extern_type(i)%cascade_list(m)%clist(l)=n

     end do

101  continue
     call abnormal_stop("readextn",&
          "Error occurs during reading the cascade samples.")

100  continue

     close(nunit)

  end do

  ! read the cdf and parameters for electron irradiation
  do i=1,n_ext
     itype=extern_type(i)%event_type

     if (itype.eq.1) cycle
     if (itype.eq.2) cycle

     call log_msg1(lunit,"")

     pos1=0

     pos2=pos1+3
     write(str(pos1+1:pos2),'("[",i1,"]")') i
     pos1=pos2

     pos2=pos1+25
     write(str(pos1+1:pos2),'(1x,"electron irradiation (3)")')
     pos1=pos2

     call log_msg1_indent(lunit,in1,str(1:pos2))

     ! read the cdf for dpa calculation
     open(unit=nunit,file=extern_type(i)%dpa_filename,status='old')

     ! number of bins
     read(nunit,*) n
     extern_type(i)%n_dpa=n
     allocate(extern_type(i)%dgrid(n))
     allocate(extern_type(i)%dprob(n))
     allocate(extern_type(i)%count_dpa(n))

     ! write the table to the log file
     call drawline(lunit,in1,42)
     write(str(1:38),'(2x,"ID",2x,&
                       3x,"e1(eV)",3x,&
                       3x,"e2(eV)",3x,&
                       3x,"int_R")')
     call log_msg1_indent(lunit,in1,str(1:38))
     call drawline(lunit,in1,42)

     ! initialize the length of the cdf for dpa calculation
     call log_msg1_indent(lunit,in1,"> Recoil spectrum")
     extern_type(i)%dlength=0

     ! read the cdf
     do j=1,n
        read(nunit,*) e1,e2,p
        extern_type(i)%dgrid(j)=e2
        extern_type(i)%dprob(j)=p
        extern_type(i)%count_dpa(j)=0
        ! Print to the log file
        write(str(1:41),'("[",i3.3,"]",1x,&
             1pe11.5,1x,1pe11.5,1x,1pe11.5)') &
             j,e1,e2,p
        call log_msg1_indent(lunit,in1,str(1:41))
     end do

     ! set the length of the cdf for dpa calculation
     extern_type(i)%dlength=p
     
     close(nunit)

     call drawline(lunit,in1,42)

     ! Determine the types of objects
     allocate(extern_type(i)%source_type(&
          extern_type(i)%n_type))

     do j=1,extern_type(i)%n_type
        n=str2label(extern_type(i)%source_name(j))
        if (n.eq.0) call abnormal_stop("readextn",&
             "The object type specified in electron irradiation &
             is not recognized.")
        extern_type(i)%source_type(j)=n
     end do

  end do

  ! Write the message to the terminal and log file
  call log_msg1(lunit,"")  
  call print_d_time(t_array0,d_time_str)
  if (myrank.eq.0) &
       write(*,'(a8,":READEXTN DONE.")') d_time_str(1:8)
  write(lunit,'(a8,":READEXTN DONE.")') d_time_str(1:8)

  return

end subroutine readextn
